package com.example.process;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Queue;

public class MLFQSimulation extends JFrame {
    private final MLFQScheduler scheduler = new MLFQScheduler();
    private final Timer timer = new Timer(1000, this::updateStep);
    private final QueuePanel[] queuePanels = new QueuePanel[3];
    private QueuePanel blockedPanel;
    private final JLabel currentProcessLabel = new JLabel("无进程执行", JLabel.CENTER);
    private final JLabel timeLabel = new JLabel("时间: 0", JLabel.CENTER);
    private int currentTime = 0;

    // 使用更现代化的配色方案
    private final Color[] queueColors = {
            new Color(255, 102, 102),  // 高优先级 - 红色
            new Color(255, 178, 102),  // 中优先级 - 橙色
            new Color(102, 178, 255)   // 低优先级 - 蓝色
    };
    private final Color blockedColor = new Color(204, 204, 204); // 阻塞队列 - 灰色
    private final Color executingColor = new Color(153, 255, 153); // 执行中 - 亮绿色

    public MLFQSimulation() {
        setupUI();
        initDemoProcesses();
        setTitle("MLFQ调度模拟器 - 优化版");
        setSize(1200, 700);  // 增大窗口尺寸
        setDefaultCloseOperation(EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void setupUI() {
        // 使用更现代化的主面板布局
        JPanel mainPanel = new JPanel(new BorderLayout(10, 10));
        mainPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 15, 15));
        mainPanel.setBackground(new Color(240, 240, 240));

        // 顶部控制面板
        JPanel controlPanel = createControlPanel();
        mainPanel.add(controlPanel, BorderLayout.NORTH);

        // 中间队列面板
        JPanel queuesPanel = createQueuesPanel();
        mainPanel.add(queuesPanel, BorderLayout.CENTER);

        // 底部状态面板
        JPanel statusPanel = createStatusPanel();
        mainPanel.add(statusPanel, BorderLayout.SOUTH);

        setContentPane(mainPanel);
    }

    private JPanel createControlPanel() {
        JPanel panel = new JPanel(new FlowLayout(FlowLayout.CENTER, 20, 10));
        panel.setBackground(new Color(230, 230, 230));
        panel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(new Color(200, 200, 200), 1),
                BorderFactory.createEmptyBorder(10, 10, 10, 10)
        ));

        // 开始/暂停按钮
        JButton startBtn = new JButton("开始");
        startBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
        startBtn.setPreferredSize(new Dimension(100, 40));
        startBtn.addActionListener(e -> toggleTimer(startBtn));

        // 单步执行按钮
        JButton stepBtn = new JButton("单步执行");
        stepBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
        stepBtn.setPreferredSize(new Dimension(120, 40));
        stepBtn.addActionListener(e -> updateStep(null));

//        // 添加进程按钮
//        JButton addProcessBtn = new JButton("添加进程");
//        addProcessBtn.setFont(new Font("微软雅黑", Font.BOLD, 14));
//        addProcessBtn.setPreferredSize(new Dimension(120, 40));
//        addProcessBtn.addActionListener(e -> showAddProcessDialog());

        panel.add(startBtn);
        panel.add(stepBtn);
//        panel.add(addProcessBtn);

        return panel;
    }

    private JPanel createQueuesPanel() {
        JPanel panel = new JPanel(new GridLayout(1, 4, 15, 15));
        panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
        panel.setBackground(new Color(240, 240, 240));

        // 初始化队列面板
        String[] titles = {
                "高优先级队列 (4ms)",
                "中优先级队列 (6ms)",
                "低优先级队列 (8ms)",
                "阻塞队列"
        };

        for (int i = 0; i < 3; i++) {
            queuePanels[i] = new QueuePanel(titles[i], queueColors[i]);
            panel.add(queuePanels[i]);
        }

        blockedPanel = new QueuePanel(titles[3], blockedColor);
        panel.add(blockedPanel);

        return panel;
    }

    private JPanel createStatusPanel() {
        JPanel panel = new JPanel(new GridLayout(1, 2, 10, 10));
        panel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(new Color(200, 200, 200), 1),
                BorderFactory.createEmptyBorder(10, 10, 10, 10)
        ));
        panel.setBackground(new Color(230, 230, 230));

        // 当前进程显示
        currentProcessLabel.setOpaque(true);
        currentProcessLabel.setBackground(executingColor);
        currentProcessLabel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(new Color(0, 150, 0), 2),
                BorderFactory.createEmptyBorder(10, 10, 10, 10)
        ));
        currentProcessLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));

        // 时间显示
        timeLabel.setOpaque(true);
        timeLabel.setBackground(new Color(220, 220, 255));
        timeLabel.setBorder(BorderFactory.createCompoundBorder(
                BorderFactory.createLineBorder(new Color(100, 100, 255), 2),
                BorderFactory.createEmptyBorder(10, 10, 10, 10)
        ));
        timeLabel.setFont(new Font("微软雅黑", Font.BOLD, 16));

        panel.add(currentProcessLabel);
        panel.add(timeLabel);

        return panel;
    }

    private void showAddProcessDialog() {
        JTextField idField = new JTextField();
        JTextField timeField = new JTextField();

        Object[] message = {
                "进程ID:", idField,
                "执行时间(ms):", timeField
        };

        int option = JOptionPane.showConfirmDialog(
                this,
                message,
                "添加新进程",
                JOptionPane.OK_CANCEL_OPTION
        );

        if (option == JOptionPane.OK_OPTION) {
            try {
                int id = Integer.parseInt(idField.getText());
                int time = Integer.parseInt(timeField.getText());
                scheduler.addProcess(new PCB(id, time));
                updateUI();
            } catch (NumberFormatException e) {
                JOptionPane.showMessageDialog(this, "请输入有效的数字!", "错误", JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    private void toggleTimer(JButton btn) {
        if (timer.isRunning()) {
            timer.stop();
            btn.setText("开始");
        } else {
            timer.start();
            btn.setText("暂停");
            btn.setBackground(new Color(255, 150, 150));
        }
    }

    private void updateStep(ActionEvent e) {
        currentTime++;
        timeLabel.setText("时间: " + currentTime);
        scheduler.scheduleStep();
        updateUI();
    }

    private void updateUI() {
        SwingUtilities.invokeLater(() -> {
            for (int i = 0; i < 3; i++) {
                queuePanels[i].updateProcesses(scheduler.getReadyQueue(i));
            }
            blockedPanel.updateProcesses(scheduler.getBlockedQueue());

            PCB current = scheduler.getCurrentProcess();
            if (current != null) {
                currentProcessLabel.setText(String.format("当前执行: P%d (剩余 %dms)",
                        current.id, current.remainingTime));
                animateCurrentProcess(current);
            } else {
                currentProcessLabel.setText("无进程执行");
            }
        });
    }

    private void animateCurrentProcess(PCB process) {
        JLayeredPane layeredPane = getLayeredPane();

        JLabel movingBlock = new JLabel("P" + process.id, JLabel.CENTER);
        movingBlock.setOpaque(true);
        movingBlock.setBackground(executingColor);
        movingBlock.setBorder(BorderFactory.createLineBorder(Color.GREEN.darker(), 2));
        movingBlock.setFont(new Font("微软雅黑", Font.BOLD, 14));
        movingBlock.setBounds(currentProcessLabel.getBounds());

        layeredPane.add(movingBlock, JLayeredPane.POPUP_LAYER);

        Timer animationTimer = new Timer(50, e -> {
            Rectangle bounds = movingBlock.getBounds();
            if (bounds.y > 50) {
                movingBlock.setBounds(bounds.x, bounds.y - 10, bounds.width, bounds.height);
            } else {
                ((Timer)e.getSource()).stop();
                layeredPane.remove(movingBlock);
                repaint();
            }
        });
        animationTimer.start();
    }

    private void initDemoProcesses() {
        int[][] demoData = {{1, 3}, {2, 8}, {3, 20}, {4, 15}, {5, 12}};
        for (int[] data : demoData) {
            scheduler.addProcess(new PCB(data[0], data[1]));
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> {
            try {
                // 设置更现代化的外观
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception e) {
                e.printStackTrace();
            }

            MLFQSimulation simulation = new MLFQSimulation();
            simulation.setVisible(true);
        });
    }

    // 优化的队列面板内部类
    class QueuePanel extends JPanel {
        private final DefaultListModel<PCB> model = new DefaultListModel<>();
        private final JList<PCB> list = new JList<>(model);
        private final JLabel countLabel = new JLabel("0 个进程", JLabel.CENTER);

        public QueuePanel(String title, Color bgColor) {
            setLayout(new BorderLayout(5, 5));
            setBackground(bgColor);
            setBorder(BorderFactory.createCompoundBorder(
                    BorderFactory.createTitledBorder(
                            BorderFactory.createLineBorder(Color.GRAY, 1),
                            title,
                            javax.swing.border.TitledBorder.CENTER,
                            javax.swing.border.TitledBorder.TOP,
                            new Font("微软雅黑", Font.BOLD, 14),
                            Color.BLACK
                    ),
                    BorderFactory.createEmptyBorder(10, 10, 10, 10)
            ));

            // 自定义列表渲染器
            list.setCellRenderer(new DefaultListCellRenderer() {
                @Override
                public Component getListCellRendererComponent(JList<?> list, Object value,
                                                              int index, boolean isSelected, boolean cellHasFocus) {
                    PCB p = (PCB) value;
                    String text = String.format("P%d (%dms) - %s",
                            p.id, p.remainingTime, p.state);

                    JLabel label = (JLabel) super.getListCellRendererComponent(
                            list, text, index, isSelected, cellHasFocus);

                    label.setOpaque(true);
                    label.setBackground(getStatusColor(p));
                    label.setBorder(BorderFactory.createCompoundBorder(
                            BorderFactory.createLineBorder(Color.GRAY, 1),
                            BorderFactory.createEmptyBorder(5, 10, 5, 10)
                    ));
                    label.setFont(new Font("微软雅黑", Font.PLAIN, 12));

                    return label;
                }
            });

            // 添加计数标签
            countLabel.setFont(new Font("微软雅黑", Font.BOLD, 12));
            countLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));

            add(new JScrollPane(list), BorderLayout.CENTER);
            add(countLabel, BorderLayout.SOUTH);
        }

        private Color getStatusColor(PCB p) {
            return switch (p.state) {
                case "执行中" -> executingColor;
                case "阻塞" -> new Color(220, 220, 220);
                default -> Color.WHITE;
            };
        }

        public void updateProcesses(Queue<PCB> queue) {
            model.clear();
            queue.forEach(model::addElement);
            countLabel.setText(queue.size() + " 个进程");
        }
    }
}